perm filename LISPB.RNO[VLI,LSP] blob sn#409517 filedate 1978-09-08 generic text, type T, neo UTF8
.title A system to understand incorrect programs
.c
A SYSTEM TO UNDERSTAND INCORRECT PROGRAMS 
.b 5
.c
Harald Wertz 
.b 3
.c
Universite de Paris VIII (Vincennes) 
.c
route de la tourelle 
.c
75571 Paris 
.b 20
.lm 8
.rm 52
Abstract#: 
.br
This paper presents a system (PHENARETE) which understands and improves 
incompletely defined LISP programs, such as those written by students 
beginning to program in LISP. This system takes, as input,  the program 
without any additional information. In order to understand the program, 
the system meta-evaluates it, using a library of "pragmatic rules", 
describing the construction and correction of general program constructs, 
and a set of "specialists", describing the syntax and semantics of the 
standard LISP functions.  The system can use its understanding of the 
program to detect errors in it,  to debug them and, eventually, to 
justify its proposed modifications. 
This paper gives a brief survey of the working of the system, 
emphasizing on some commented examples. 
.page
.lm 0
.rm 62
A lot of effort is actually spent on the developpement of tools to help 
programmers in constructing, debugging and verifying programs. 
Unfortunately  most of these tools 
.br
- impose too  much constraints on the 
intuitions of the programmer [cf DIJKSTRA 1976], 
.br
- are working only 
on  a very limited subset of possible programs [cf RUTH 1974],
.br
- are only 
working on correct programs [cf ARSAC 1977, IGARASHI et al 1975]. 
.b 1
Our aim is two-fold#: 
.lm 8
.p -4,1,1
   -1- to make explicit the knowledge involved in constructing and debugging 
       programs and 
.p -4,1,1
   -2- to verify - not the correctness of programs - but their "consistency" 
       and to provide "hints" for improving and correcting their programs 
       to the programmer.
.lm 0
.b 2
To this end we have build our system on four main concepts#:    
 1 an algorithm of meta-evaluation [cf GOOSSENS 1978]   
to help the system to understand  
   each of the possible paths of the program, 
.br
 2 a set of "specialists", i.e. a set of procedural specifications 
   of the syntax and the operational semantics of the standard  
   LISP functions,  
.b 
   example#: specialist CAR for the syntax  
.b   
.nofill 
   [CAR-1 (X) =>   
           v (←& atom (CAR X) 
              ←& type (X) = LISTP) 
           v (←& S-expression (CAR X) 
    	      ←& type (val (X)) = LISTP)  
     else#: 
              modify X until CAR-1 (X) = T]  
.fill 
.b 2 
paraphrasing#: 
.b
.rm 45
.lm 3 
CAR expects that its argument is 
.lm 7 
- an atom 
.lm 9    
.br
and the type of the value of the argument is a list 
.lm 7.br   
- a S-expression 
.lm 9   
.br
and the type of the value of that S-expression is a list 
.br   
.lm 5 
else 
.br    
.lm 9 
CAR has to modify the argument until one of these two conditions is true 
.b 2 
.lm 0    
.rm 62 
and the specialist CAR for the semantics 
.b 
.tp 8
.nofill 
    [CAR-N =>  
         arg#: (X (meta-eval X)) 
        test#: (type (val (X)) = LISTP) -> 
               (type (val (X)) = ?) 
		      -> hypothesize (X, type#LISTP) 
     	       T -> complain (X, type#: LISTP) 
      action#: if (existe (CAR X)) --> (CAR X) 
               else (create (CAR, X)) --> (CAR X)] 
.fill 
.b 2 
or in paraphrasing#: 
.rm 55
.b
.lm 4 
CAR-N 
.b  
.lm 7 
has an argument named X, which must   be evaluated   
.br
one must verify   
.br 
.lm 9 
if 
.lm 12
  the type of value of the argument is a list, all is ok   
.lm 9
else 
.lm 12
if the type of value of the argument isn't known, one has to 
create a hypothetical value of type LIST for X 
.lm 9 
else    
.lm 12
one has to ask the debugger to change the text of the program 
in such a way that the value of X becomes a list 
.b
.lm 7 
the value of CAR is 
.br
.lm 9 
if 
.lm 12
there exists already a CAR of X, this CAR 
.lm 9
.br
else 
.lm 12
one has to create a symbolic value for X, the CAR of which 
will be the desired value 
.lm 0 
.rm 62 
.b 2
These specialists are the agents of the meta-evaluation and 
they represent the system's knowledge about the programming 
language used.
.b
3 a set of "pragmatic rules" describing general program constructs and 
methods to repair inconsistencies
.b
example#:  
.br
.lm 5
.rm 55 
rule of the dependence of a loop of the predicate#=> 
.b
if no variable of the exit-test is modified inside the loop,
then the loop is independent of the exit-test  and,          
its execution is non-terminating or the loop will never be 
executed.       
.b
.lm 0
.rm 62
The set of these rules expresses the system's general knowledge  
about the well-formedness of programs and about the correction of errors;
.b
4 during the analysis of a program, PHENARETE contructs some description 
-#an internal representation#- of the program under the form of 
"cognitive atoms". These may be considered as the nodes of a  
network-like representation of the program actually analysed.
.b 2 
The system accepts every LISP program conforming to the following 
restrictions#: 
.br
.lm 5
.p -2,1,1
- partitioning of the names of variables, funtions and labels;
.p -2,1,1
- all funtion calls must be  "call by name";
.p -2,1,1
- the unique functional arguments admitted are explicit lambda-expressions.
.b 
.lm 0 
We call this subset of LISP#:  extended first order LISP.
.b 2   
To use  PHENARETE,  the user has to  give to the system only  
the text of the draft version of the program he wants to write, 
without any additional information like input/output assertions,
commentaries, plans etc. The system will try to understand what the 
user  wanted to do, and, if necessary, modify                          
                the text of the programm.   
.b 2
To give some feeling of the working of the system, let us examine 
some examples in detail#:
.br
Our first example is a (very) erroneous version of the well known 
REVERSE function. Here is the actual input to the system#:
.b   
.nofill 
?  (P '(DE REV L1 L2 COND ULL L22 A1 T RVE A1 ONS CRA A1 A2))
.fill
.b
PHENARETE will first 
correct the spelling errors#:
.b
.nofill
   ERREUR: 
              NOM --> (? ULL --> NULL)
   ERREUR: 
              NOM --> (? L22 --> L2)
   ERREUR: 
              NOM --> (? A1 --> L1)
   ERREUR: 
              NOM --> (? A1 --> L1)
   ERREUR: 
              NOM --> (? RVE --> REV)
   ERREUR: 
              NOM --> (? RVE --> REV)
   ERREUR: 
              NOM --> (? A1 --> L1)
   ERREUR: 
              NOM --> (? ONS --> CONS)
   ERREUR: 
              NOM --> (? CRA --> CAR)
   ERREUR: 
              NOM --> (? A1 --> L1)
   ERREUR: 
              NOM --> (? A2 --> L2)
 
.fill
.b
After having very well corrected the spelling errors, PHENARETE  
proceeds to a first analysis where she uses only her syntactic 
knowledge. The result of this first analysis is a "syntactically 
correct" LISP program (i.e. a programm accepted by any smart     
LISP interpreter or compiler)#: 
.b   
.tp 7
.nofill
   PROPOSITION 1 : 
  
   (DE REV (L1 L2) 
      (COND
         ((NULL L2) L1)
         (T (REV L1 (CONS (CAR L1) L2)))))
.fill
.b
These first improvements have eliminated all the syntactic errors.
Anyway, there subsist two    semantic errors#:  
.lm 5
.p -3,1,1 
-1  in the recursive call of rev, the first argument L1 is not 
modified. This creates an infinit recursion.
.p -3,1,1
-2  even with a modification of L1 in the recursive call, the 
recursion won't stop either since the stop-test has as argument L2, 
a list which grows longer and longer in the run of the succesive 
recursive calls.
.b
.lm 0
PHENARETE can not disambiguate this function -#she does not know 
anything of the intentions of the programmer#- so she gives two 
different propositions#: 
.b
.nofill 
PROPOSITION 2 : 
            
   (DE REV (L1 L2) 
      (COND
         ((NULL L2) L1)
         ((NULL L1) L2)
         (T (REV (CDR L1) (CONS (CAR L1) L2)))))
            
              AT LEAST YOUR FUNCTION SEEMS OK TO ME.
            
.fill 
In this first proposition, PHENARETE supposed the stop-test given 
to be true, but that the user omitted a second stop-test for the case 
where the second argument is not NULL at the initial call of REV. 
.b 
.tp 8
.nofill
            
   P R O P O S I T I O N :
  
   (DE REV (L1 L2) 
      (COND
         ((NULL L1) L2)
         (T (REV (CDR L1) (CONS (CAR L1) L2)))))
   
              AT LEAST YOUR FUNCTION SEEMS OK TO ME.
.fill 
.b
In this second proposition, PHENARETE supposed that the user 
inadvertently inverted the  arguments of the stop-test, so 
she inverts the two arguments L1 and L2.
.br
Of the two corrected versions of the initial draft-program 
PHENARETE is assured that they will stop and deliver a result when    
running.       
.b 2
Our second example is an extremly "simplified" version of 
the equally well known function FACTORIAL. Here she is#:
.b
.nofill         
?  (DE FACT N TIMES N FACT N)
.fill
.b
As in the previous example, PHENARETE will first translate this 
unparentesized expression into an well parentesized one#:        
.b
.nofill
   PROPOSITION 1 : 
  
   (DE FACT (N) (TIMES N (FACT N)))
.fill
.b
This first proposition is a syntactically correct program, but 
semantically it is not very correct#:
.lm 5
.b
.p -2,1,1
-1 at the recursive call N is not modified. This is  
the same kind of error as in the previous example, exept the   
argument here is of numeric type.
.p -2,1,1
-2 there is no stop-test at all, so there are two (!) reasons 
to make the recursion infinit.
.lm 0
.b  
Remember that PHENARETE doesn't know the intentions of the 
programmer, so she must detect these errors without any 
additional information#: all she can use in the further analysis
are the semantic specialists and the pragmatic rules. So let us look 
at her proposition#: 
.b                 
.nofill 
  P R O P O S I T I O N :
  
   (DE FACT (N) (COND
      ((LE N 0) 1)
      (T (TIMES N (FACT (SUB1 N))))))
   
              AT LEAST YOUR FUNCTION SEEMS OK TO ME.
.fill
.b
This corrected version is actually a correct version of the 
factorial-program. The performance is  really astonishing 
knowing that the system works completely automatically whithout 
asking any question to the user and without any information about 
the supposed intention. 
.b2
One last (uncommented) example#:
.b
.nofill               
?  (DE ADDIT M N  ((ZEROP N) M)    
                  (T (ADDIT SUB1 M ADD1 N)))
   
   PROPOSITION 1 : 
  
  (DE ADDIT (M N) 
      (COND
         ((ZEROP N) M)
         (T (ADDIT (SUB1 M) (ADD1 N)))))
  
  
   P R O P O S I T I O N :
  (DE ADDIT (M N) 
      (COND
         ((ZEROP N) M)
         ((LE M 0) N)
         (T (ADDIT (SUB1 M) (ADD1 N)))))
   
              AT LEAST YOUR FUNCTION SEEMS OK TO ME.
     
.fill  
.b 2 
Presently we are working on some extensions as to find automatically 
the intentions and the goals of given pieces of code. We would also 
like to adjoin to PHENARETE a module permitting to explain the reasoning 
of the system. This would be a  great help to the user. 
.br
The system is running on PDP-10, uses about 25k word memory, is implemented 
in VLISP [CHAILLOUX 1976, GREUSSAY 1977], and is used by about 
1000 students in our university.  
.br 
A more detailed description may be found in [WERTZ 1978].

.page
.c 
references
.b
.lm 10
.p -10,1,1
ARSAC J., (1977), La construction de programmes structures, 
Dunod-Informatique, Paris 
.p -10,1,1
CHAILLOUX J., (1976), VLISP-10 manuel de reference, 
Dept. Informatique, Universite Paris 8, RT-17-76    
.p -10,1,1
DIJKSTRA E.W., (1976), A Discipline of Programming, 
Prentice-Hall, Inc., Englewood Cliffs, N.J. 
.p -10,1,1
GOOSSENS D., (1978), A System For Visual-Like Understanding of 
LISP Programs, Proc. AISB/GI Conference, Hamburg, RFA,  
july 17-19, 1978  
.p -10,1,1
GREUSSAY P., (1977), Contribution a la Definition 
Interpretative 
et a l'Implementation des Lambda-langages, These, Universite Paris#7.
.p -10,1,1
IGARASHI S., LONDON R.L. ←& LUCKHAM D.C., (1975), Automatic 
Program 
Verification 1#: Logical Basis and its Implementation, Acta Informatica, 
vol. 4, pp. 145-182.
.p -10,1,1
RUTH G.R., (1974), Analysis of Algorithm Implementations, 
M.I.T., MAC-TR-130. 
.p -10,1,1
WERTZ H., (1978), Un systeme de comprehension, d'amelioration 
et de correction de programmes incorrects, These de 3eme cycle, 
Universite Paris 6